package lib

import (
	"GameServer/Common/utils"
	"fmt"
	"math"

	"GameServer/Common/data"
	"GameServer/Game/errors"
	"GameServer/Game/m"
)

type MatchUsers []*m.User

func (mus MatchUsers) Len() int {
	return len(mus)
}

func (mus MatchUsers) Swap(i, j int) {
	mus[i], mus[j] = mus[j], mus[i]
}

func (mus MatchUsers) Less(i, j int) bool {
	return mus[i].Pos.LockBlockTid < mus[j].Pos.LockBlockTid
}

func SloctMatchs(lockBlockTid int64, list []*m.User) (user *m.User, err error) {
	list1 := make([]*m.User, 0)
	for _, item := range list {
		// 1、不是新手玩家
		// 2、玩家金币少于25W
		// 3、关卡信息相差大于9或小于9
		// 不进入匹配
		if item.MaxPos.LockBlockTid <= data.SlotFreshmanProtectEnum.FreshManCardId ||
			item.Gold < data.SlotLimitGold ||
			item.MaxPos.LockBlockTid < lockBlockTid-data.SlotLockBlockLimit ||
			item.MaxPos.LockBlockTid > lockBlockTid+data.SlotLockBlockLimit {
			continue
		}
		list1 = append(list1, item)
	}
	if len(list1) == 0 {
		err = errors.New("没有匹配到玩家")
		return
	}

	// 匹配玩家，关卡离自己最近的人优先匹配。
	mus := make([]*m.User, 0)
	for matchNum := int64(1); len(mus) == 0; matchNum++ {
		for _, item := range list1 {
			if lockBlockTid-matchNum <= item.MaxPos.LockBlockTid && item.MaxPos.LockBlockTid <= lockBlockTid+matchNum {
				mus = append(mus, item)
			}
		}
	}
	// 随机匹配玩家
	index := utils.RandomInt(0, len(mus)-1)
	return mus[index], nil
}

// func SlotFireMatchs(lockBlockTid int64, list []*m.User) (user *m.User, err error) {
// 	list1 := make([]*m.User, 0)
// 	for _, item := range list {
// 		// 1、打开的格子数 <=2
// 		// 2、新手保护
// 		// 3、关卡信息相差大于9或小于9
// 		// 不进入匹配
// 		if item.Pos.LayerOpenGridNum <= 2 ||
// 			item.MaxPos.LockBlockTid <= data.SlotFreshmanProtectEnum.FreshManCardId ||
// 			item.MaxPos.LockBlockTid < lockBlockTid-data.SlotLockBlockLimit ||
// 			item.MaxPos.LockBlockTid > lockBlockTid+data.SlotLockBlockLimit {
// 			continue
// 		}
// 		layerTemp := item.GetLayer()
// 		layerT, ok := getLayerTByTid(uint64(layerTemp.Tid))
// 		if ok && layerT.Layer_type == 1 {
// 			// 玩家在boss楼层，不进入匹配
// 			continue
// 		}
// 		list1 = append(list1, item)
// 	}
// 	// 玩家被过滤完，生成机器人。
// 	if len(list1) == 0 {
// 		err = errors.New("没有匹配到玩家")
// 		return
// 	}

// 	// 匹配玩家，关卡离自己最近的人优先匹配。
// 	mus := make([]*m.User, 0)
// 	for matchNum := int64(1); len(mus) == 0; matchNum++ {
// 		for _, item := range list1 {
// 			if lockBlockTid-matchNum <= item.MaxPos.LockBlockTid && item.MaxPos.LockBlockTid <= lockBlockTid+matchNum {
// 				mus = append(mus, item)
// 			}
// 		}
// 	}
// 	// 随机匹配玩家
// 	index := utils.RandomInt(0, len(mus)-1)
// 	return mus[index], nil
// }

// 老虎机摇奖
func SlotReward(from string, u *m.User, spin int64, gmKey uint64, PSend func(interface{}) error) (key int64, uProp *m.UpdateProp, res []*m.Goods, err error) {
	rList, ok := data.GetAllDatas("SlotEvents")
	if !ok || len(rList) == 0 {
		err = errors.NewErrcode(data.Errcode.ConfigNotFound, "没有找到SlotEvents配置表")
		return
	}
	// 激活活动表格
	nowTime := utils.TNow().Unix()
	var slot777Act, slot888Act bool = false, false
	actList, actErr := GetActActivityList() //读表
	if actErr == nil {
		for _, value := range actList {
			if IsSlotAct(int64(value.ActivId)) {
				configInfo, actErr := GetSlotActConfigeTableInfo(int64(value.ActivId))
				if actErr == nil {
					if configInfo.TigerGain > 0 {
						beginTime, _ := utils.LayoutToTime(value.BeginTime)
						endTime, _ := utils.LayoutToTime(value.EndTime)
						if nowTime > beginTime.Unix() && nowTime < endTime.Unix() {
							slot777Act = true
						}
					}
				}
			}
			if int64(value.ActTyp) == data.ActivityEnum.Jackpot {
				slot888Act = true
			}
		}
	}
	// 新手玩家不能有活动事件
	if u.MaxPos.LockBlockTid < 2 {
		slot777Act = false
		slot888Act = false
	}
	if (gmKey == 777 && !slot777Act) || (gmKey == 888 && !slot888Act) {
		gmKey = 0
	}

	weights := make([]data.WeightV, len(rList))
	slotEvents := make([]data.SlotEvent, len(rList))
	for i, item := range rList {
		slotEventT := item.(data.SlotEvent)
		if (slotEventT.Type == 7 && !slot777Act) || (slotEventT.Type == 8 && !slot888Act) {
			continue
		}
		var randValue uint64 = 0
		for _, randvItem := range slotEventT.Randv {
			if int64(randvItem.Key) == spin {
				randValue = randvItem.Value
				break
			}
		}
		weights[i] = data.WeightV{Value: i, Weight: randValue}
		slotEvents[i] = slotEventT
	}

	weight := utils.RandomWeight(weights)
	index := utils.Int64(weight.Value)
	weight = utils.RandomWeight(slotEvents[int(index)].Slots)

	keyIndex := utils.Uint64(weight.Value)

	if gmKey > 0 {
		keyIndex = gmKey
	}

	slotTpl, ok := data.Get("Slots", keyIndex)
	if !ok {
		err = errors.NewErrcode(data.Errcode.ConfigNotFound, fmt.Sprintf("没有找到老虎机slot配置, id:%d, gmKey:%d", utils.Int64(weight.Value), gmKey))
		return
	}

	costItem := m.BaseKV{Key: data.GlobalEnum.Energy, Val: spin}

	uProp, err = Cost(from, u, []m.BaseKV{costItem})
	if err != nil {
		return
	}
	// 成就，记录消耗体力
	AddAchievProgress(u, data.AchievementType.Use_spins, costItem.Val)

	slotT := slotTpl.(data.Slot)
	key = int64(slotT.Key)

	if len(slotT.Rewards) > 0 {
		giveGoods := getSlotRewards(u.SlotLv, slotT, spin)
		uProp1, resGoods, _, err := GiveGoodsByKv(from, u, giveGoods, PSend)
		if err != nil {
			return 0, nil, nil, err
		}
		uProp.Merge(uProp1)
		res = append(res, resGoods...)
	}
	return
}

// 获取老虎机奖励
func getSlotRewards(slotLv int64, slotT data.Slot, spin int64) (r m.BaseKV) {
	var baseGoods *m.BaseKV
	for _, item := range slotT.Rewards {
		if item.LayerTid == 0 {
			baseGoods = &m.BaseKV{Key: int64(item.GoodsTid), Val: int64(item.Num) * spin}
		}
		// 老虎机等级
		if int64(item.LayerTid) == slotLv {
			r = m.BaseKV{Key: int64(item.GoodsTid), Val: int64(item.Num) * spin}
			return r
		}
		if int64(item.LayerTid) > slotLv {
			break
		}
	}
	if baseGoods != nil {
		r = *baseGoods
		return
	}
	return
}

//  u 当前玩家
func SlotTheft(from string, u *m.User, goods m.Goods, goldNum int64, spin int64, PSend func(interface{}) error) (rGoods m.Goods, muProp *m.UpdateProp, res []*m.Goods, err error) {
	item := m.BaseKV{Key: goods.Tid, Val: goods.Num}
	goodsTpl, ok := data.Get("Goods", uint64(goods.Tid))
	if !ok {
		err = errors.NewErrcode(data.Errcode.ConfigNotFound, fmt.Sprintf("没有找到goods配置,id:%d", goods.Tid))
		return
	}

	goodsT := goodsTpl.(data.Good)
	if int64(goodsT.Category) == data.GoodsCategoryEnum.CategoryLv5 && int64(goodsT.Type) == data.GlobalEnum.Gold {
		goods.Num *= spin
		item.Val = goods.Num
	}

	var list []m.BaseKV

	if goldNum > 0 {
		if int64(goodsT.Category) == data.GoodsCategoryEnum.CategoryLv5 && int64(goodsT.Type) == data.GlobalEnum.Gold {
			item.Val += goldNum
			list = append(list, item)
		} else {
			list = append(list, item)
			list = append(list, m.BaseKV{Key: data.GlobalEnum.Gold, Val: goldNum})
		}

	} else {
		list = append(list, item)
	}
	muProp, resGoods, boxResList, err := GiveGoodsByKvList(from, u, list, PSend)
	if err != nil {
		return
	}
	rGoods = goods
	if int64(goodsT.Category) == data.GoodsCategoryEnum.CategoryLv5 && int64(goodsT.Type) == data.GlobalEnum.Gold {
		res = resGoods
	} else {
		if len(boxResList) > 0 {
			res = boxResList[0].Res //resGoods
		} else {
			res = resGoods
		}
	}
	return
}

// 获取宝箱奖励
func SlotTheftBoxs(u, tu *m.User) (goldNum int64, tGoldNum int64, r []m.Goods, petGoods m.Goods, tuProp *m.UpdateProp, err error) {
	uNewGuide := u.GetNewGuide()
	goldNum = 0
	// 新手引导生成的老虎机宝箱配置
	if !uNewGuide.SlotFlag && u.MaxPos.LockBlockTid == 1 {
		list, ok := data.GetAllDatas("NewGuildSlotBoxs")
		if !ok {
			err = errors.NewErrcode(data.Errcode.ConfigNotFound, "没有偷盗事件NewGuildSlotBoxs宝箱奖励配置")
			return
		}
		for i, item0 := range list {
			item := item0.(data.NewGuildSlotBox).Res
			goods := m.Goods{Tid: int64(item.Key), Num: int64(item.Value)}
			goldNum += goods.Num
			if i == 2 {
				petGoods = goods
				continue
			}
			r = append(r, goods)
		}
		tGoldNum = goldNum
		return
	}

	list, ok := data.GetAllDatas("SlotTheftRewards")
	if !ok {
		err = errors.NewErrcode(data.Errcode.ConfigNotFound, "没有偷盗事件宝箱奖励配置")
		return
	}

	stpl, ok := data.Get("SlotTheftProportions", uint64(1))
	if !ok {
		err = errors.NewErrcode(data.Errcode.ConfigNotFound, "没有老虎机事件获取比列配置")
		return
	}

	slotLevel, ok := data.Get("SlotLvMatchSkins", uint64(u.SlotLv))
	if !ok {
		err = errors.NewErrcode(data.Errcode.ConfigNotFound, "找不到老虎机等级配置")
		return
	}

	itemSlotLvMatchSkin := slotLevel.(data.SlotLvMatchSkin)
	stealLitmit := int64(itemSlotLvMatchSkin.StealLitmit)

	stProportion := stpl.(data.SlotTheftProportion)
	var val int64 = ((int64(float64(tu.Gold)*float64(stProportion.Proportion)/float64(100)) + 50) / 100) * 100

	if val > stealLitmit && stealLitmit != 0 {
		val = stealLitmit
	}

	//goldNum = val
	tGoldNum = val - int64(float64(val)*float64(tu.TheftGoldRate)/float64(100))
	costItem := m.BaseKV{Key: data.GlobalEnum.Gold, Val: tGoldNum}

	tuProp, err = Cost("SlotTheftBoxs", tu, []m.BaseKV{costItem})
	if err != nil {
		return
	}

	var list0 []data.WeightV
	for _, item := range list {
		t := item.(data.SlotTheftReward)
		randv := utils.RandomInt64(1, 100)
		goods := m.Goods{Tid: goldGoods.Tid}
		if randv > utils.Int64(t.Randv) {
			w0 := utils.RandomWeight(t.Res)
			goodTid := utils.Int64(w0.Value)
			if goodTid != 0 {
				goods = m.Goods{Tid: goodTid, Num: 1}
			}
			//r = append(r, goods)
			list0 = append(list0, data.WeightV{Weight: uint64(t.Weight), Value: goods})
			continue
		}

		var num int64 = int64(float64(val) * float64(utils.Int64(t.Percent)) / 100)
		goods.Num = num

		if t.Id == 2 {
			petGoods = goods
			//continue
		}
		list0 = append(list0, data.WeightV{Weight: t.Weight, Value: goods})
	}

	getIndex := func(val data.WeightV, list []data.WeightV) (index int) {
		goodsVal := val.Value.(m.Goods)
		index = 0
		var goodsItem m.Goods
		for i, item := range list {
			goodsItem = item.Value.(m.Goods)
			if goodsVal.Tid == goodsItem.Tid && goodsVal.Num == goodsItem.Num {
				index = i
				break
			}
		}
		return
	}

	count := len(list0)

	r = make([]m.Goods, 0)
	var listRandomResult data.WeightV
	index := 0
	for i := 0; i < count; i++ {
		listRandomResult = utils.RandomWeight(list0)
		r = append(r, listRandomResult.Value.(m.Goods))
		index = getIndex(listRandomResult, list0)
		list0 = append(list0[:index], list0[index+1:]...)
	}
	return
}

// 放火
// func SlotFire(from string, u *m.User, tu *m.User, gridIds []int64, spin int64, PSend func(interface{}) error) (uProp *m.UpdateProp, resGoods *m.Goods, err error) {
// 	uProp = m.NewUpdateProp()

// 	slotLv := u.SlotLv

// 	slotFireRewardTpl, ok := data.Get("SlotFireRewards", uint64(slotLv))
// 	if !ok {
// 		err = errors.NewErrcode(data.Errcode.ConfigNotFound, fmt.Sprintf("没有找到老虎机事件奖励SlotFireRewards配置, id:%d", slotLv))
// 		return
// 	}
// 	slotFireRewardT := slotFireRewardTpl.(data.SlotFireReward)

// 	// 宠物技能几率抵挡
// 	rateVal := tu.GetUserPet().GetSkillVal(uint64(data.PetSkillEffectEnum.AddShield))

// 	fmt.Printf("SlotFire--->uname:%s tuname:%s  rateVal:%v tu.pet:%v\n", u.Name, tu.Name, rateVal, utils.Obj2JsonStr(tu.GetUserPet()))
// 	if rateVal > 0 {
// 		ratev := utils.RandomInt64(1, 100)
// 		fmt.Printf("SlotFire--->uname:%s  tuname:%s rateVal:%v, ratev:%v\n", u.Name, tu.Name, rateVal, ratev)
// 		if ratev <= int64(rateVal) {
// 			fmt.Printf("SlotFire--->uname:%s tuname:%s 宠物技能几率抵挡\n", u.Name, tu.Name)
// 			uProp, resGoodsList, _, err := GiveGoodsByKv(from, u, m.BaseKV{Key: int64(slotFireRewardT.ShieldRes.Key), Val: utils.Int64(slotFireRewardT.ShieldRes.Value) * spin}, PSend)
// 			if err != nil {
// 				return nil, nil, err
// 			}
// 			err = errors.NewErrcode(data.Errcode.HasPetSkillShield, "宠物技能几率抵挡")
// 			resGoods = resGoodsList[0]
// 			return uProp, resGoods, err
// 		}
// 	}

// 	// 扣对方盾牌
// 	_, err = Cost(from, tu, []m.BaseKV{{Key: data.GlobalEnum.Shield, Val: 1}})
// 	if err == nil {
// 		uProp, resGoodsList, _, err := GiveGoodsByKv(from, u, m.BaseKV{Key: int64(slotFireRewardT.ShieldRes.Key), Val: utils.Int64(slotFireRewardT.ShieldRes.Value) * spin}, PSend)
// 		if err != nil {
// 			return nil, nil, err
// 		}
// 		err = errors.NewErrcode(data.Errcode.HasShield, "有盾牌保护")
// 		resGoods = resGoodsList[0]
// 		return uProp, resGoods, err
// 	}
// 	//挖对方格子
// 	// 把玩家 格子变成焦土格子
// 	cntfree, err := changeGridFireStatus(tu, gridIds, true, u)
// 	if err != nil {
// 		return nil, nil, err
// 	}
// 	//计算奖励的金币
// 	val := utils.Int64(slotFireRewardT.NoShieldRes.Value) * spin
// 	// 完美攻击，被攻击的9个格子状态都为0，奖励金币1.5倍。
// 	if cntfree == 9 {
// 		val = val * 3 / 2
// 	}
// 	// 获得 全部奖励
// 	uProp, resGoodsList, _, err := GiveGoodsByKv(from, u, m.BaseKV{Key: int64(slotFireRewardT.NoShieldRes.Key), Val: val}, PSend)
// 	if err != nil {
// 		return nil, nil, err
// 	}
// 	resGoods = resGoodsList[0]
// 	return uProp, resGoods, nil
// }

//放火，攻击在线玩家 u：攻击玩家，tu：被攻击玩家，gridIds：被攻击格子坐标，spin：倍率，burn 是否将格子烧毁
func SlotFireOn(from string, u *m.User, tu *m.User, gridIds []int64, midId int64, spin int64, burn bool, PSend func(interface{}) error) (uProp *m.UpdateProp, tuProp *m.UpdateProp, resGoods *m.Goods, err error) {
	uProp = m.NewUpdateProp()

	slotLv := u.SlotLv

	slotFireRewardTpl, ok := data.Get("SlotFireRewards", uint64(slotLv))
	if !ok {
		err = errors.NewErrcode(data.Errcode.ConfigNotFound, fmt.Sprintf("没有找到老虎机事件奖励SlotFireRewards配置, id:%d", slotLv))
		return
	}
	slotFireRewardT := slotFireRewardTpl.(data.SlotFireReward)

	// 若tu有盾
	destroyShieldOccur := false
	if tu.Shield > 0 {
		// 1、没有犬妖，扣盾。
		// 2、犬妖砍盾成功，扣盾，放火成功。
		// 3、犬妖砍盾失败，火球被盾挡住，扣盾，放火失败。
		// 扣对方盾牌
		tuProp, err = Cost(from, tu, []m.BaseKV{{Key: data.GlobalEnum.Shield, Val: 1}})
		// 获取犬妖概率
		rateValTemp := u.GetUserPet().GetSkillVal(uint64(data.PetSkillEffectEnum.DestroyShield))
		if rateValTemp > 0 { // 犬妖砍盾
			// 若u有犬妖
			ratev := utils.RandomInt64(1, 100)
			if ratev <= int64(rateValTemp) { // 1、犬妖砍盾成功
				destroyShieldOccur = true // 宠物几率破盾成功
			}
		}
		// 1、没有犬妖，扣盾。
		// 3、犬妖砍盾失败，火球被盾挡住，扣盾。
		if !destroyShieldOccur {
			uProp, resGoodsList, _, err := GiveGoodsByKv(from, u, m.BaseKV{Key: int64(slotFireRewardT.ShieldRes.Key), Val: utils.Int64(slotFireRewardT.ShieldRes.Value) * spin}, PSend)
			if err != nil {
				return nil, tuProp, nil, err
			}
			err = errors.NewErrcode(data.Errcode.HasShield, "有盾牌保护")
			resGoods = resGoodsList[0]
			return uProp, tuProp, resGoods, err
		}
	}
	// 犬妖砍盾成功，不触发护卫犬
	if destroyShieldOccur {
	} else {
		// 宠物技能几率抵挡
		rateVal := tu.GetUserPet().GetSkillVal(uint64(data.PetSkillEffectEnum.AddShield))
		if rateVal > 0 {
			ratev := utils.RandomInt64(1, 100)
			if ratev <= int64(rateVal) { //宠物几率抵挡成功
				uProp, resGoodsList, _, err := GiveGoodsByKv(from, u, m.BaseKV{Key: int64(slotFireRewardT.ShieldRes.Key), Val: utils.Int64(slotFireRewardT.ShieldRes.Value) * spin}, PSend)
				if err != nil {
					return nil, nil, nil, err
				}
				if destroyShieldOccur {
					err = errors.NewErrcode(data.Errcode.HasPetSkillDestroyShieldAndTriggerResist, "宠物技能机率破盾后被宠物技能抵挡")
				} else {
					err = errors.NewErrcode(data.Errcode.HasPetSkillShield, "宠物技能几率抵挡")
				}
				resGoods = resGoodsList[0]
				return uProp, tuProp, resGoods, err
			}
		}
	}

	// 把玩家 格子变成焦土格子
	val := utils.Int64(slotFireRewardT.NoShieldRes.Value) * spin
	if burn {
		cntfree, err := changeGridFireStatus(tu, gridIds, midId, burn, u)
		if err != nil {
			return nil, nil, nil, err
		}
		// 成就，记录玩家放火次数
		AddAchievProgress(u, data.AchievementType.SlotFire, cntfree)
		// 计算奖励的金币，完美攻击，被攻击的9个格子状态都为0，奖励金币翻倍。
		if cntfree == 9 {
			val *= 2
		}
		// 委托活动，玩家烧的焦土。
		CalcHonor(u, data.EntrType.Orc, data.EntrEnum.FireUser, cntfree*spin)
	}
	// 获得 全部奖励
	uProp, resGoodsList, _, err := GiveGoodsByKv(from, u, m.BaseKV{Key: int64(slotFireRewardT.NoShieldRes.Key), Val: val}, PSend)
	if err != nil {
		return nil, nil, nil, err
	}
	resGoods = resGoodsList[0]
	if destroyShieldOccur {
		err = errors.NewErrcode(data.Errcode.HasPetSkillDestroyShield, "犬妖砍盾成功")
	}
	return uProp, tuProp, resGoods, err
}

// 放火攻击机器人，放火，攻击在线玩家 u：攻击玩家，tu：被攻击玩家，gridIds：被攻击格子坐标，spin：
func RobotSlotFire(from string, u *m.User, tu *m.User, layer *m.Layer, gridIds []int64, spin int64, PSend func(interface{}) error) (uProp *m.UpdateProp, resGoods *m.Goods, err error) {
	uProp = m.NewUpdateProp()

	slotLv := u.SlotLv

	slotFireRewardTpl, ok := data.Get("SlotFireRewards", uint64(slotLv))
	if !ok {
		err = errors.NewErrcode(data.Errcode.ConfigNotFound, fmt.Sprintf("没有找到老虎机事件奖励SlotFireRewards配置, id:%d", slotLv))
		return
	}
	slotFireRewardT := slotFireRewardTpl.(data.SlotFireReward)

	// 若tu有盾
	destroyShieldOccur := false
	if tu.Shield > 0 {
		rateValTemp := u.GetUserPet().GetSkillVal(uint64(data.PetSkillEffectEnum.DestroyShield))
		if rateValTemp > 0 {
			// 若u有犬妖
			ratev := utils.RandomInt64(1, 100)
			if ratev <= int64(rateValTemp) {
				//宠物几率破盾成功
				destroyShieldOccur = true
			}
		}
		if !destroyShieldOccur {
			// 破盾失败
			uProp, resGoodsList, _, err := GiveGoodsByKv(from, u, m.BaseKV{Key: int64(slotFireRewardT.ShieldRes.Key), Val: utils.Int64(slotFireRewardT.ShieldRes.Value) * spin}, PSend)
			if err != nil {
				return nil, nil, err
			}
			err = errors.NewErrcode(data.Errcode.HasShield, "有盾牌保护")
			resGoods = resGoodsList[0]
			return uProp, resGoods, err
		}
	}

	// 把玩家 格子变成焦土格子
	cntfree, err := RobotChangeGridFireStatus(layer, gridIds)
	if err != nil {
		return nil, nil, err
	}
	// 成就，记录玩家放火次数
	AddAchievProgress(u, data.AchievementType.SlotFire, cntfree)
	// 委托活动，玩家烧的焦土。
	CalcHonor(u, data.EntrType.Orc, data.EntrEnum.FireUser, cntfree)
	//计算奖励的金币
	val := utils.Int64(slotFireRewardT.NoShieldRes.Value) * spin
	// 完美攻击，被攻击的9个格子状态都为0，奖励金币翻倍。
	if cntfree == 9 {
		val = val * 2
	}
	// 获得 全部奖励
	uProp, resGoodsList, _, err := GiveGoodsByKv(from, u, m.BaseKV{Key: int64(slotFireRewardT.NoShieldRes.Key), Val: val}, PSend)
	if err != nil {
		return nil, nil, err
	}

	resGoods = resGoodsList[0]
	if destroyShieldOccur {
		err = errors.NewErrcode(data.Errcode.HasPetSkillDestroyShield, "犬妖砍盾成功")
	}
	return uProp, resGoods, err
}

//把玩家当前层变成焦土，tu：玩家，gridIds：焦土坐标
func RobotChangeGridFireStatus(layer *m.Layer, gridIds []int64) (cntfree int64, err error) {
	layerT, ok := getLayerTByTid(uint64(layer.Tid))
	if !ok {
		err = errors.NewErrcode(data.Errcode.ConfigNotFound, "没有找到层配置")
		return
	}

	// 焦土格子id
	fireGridId := getFireGridTid(layerT)

	cntfree = 0 //统计变成焦土的格子数
	for _, id := range gridIds {
		gridInfo := layer.GridList[id]
		if id == layer.InGridId {
			continue
		}
		if gridInfo.Status == 2 {
			continue
		}
		cntfree++
		gridInfo.ExtId = gridInfo.Tid // 格子变成焦土，ExtId记录Tid
		gridInfo.Tid = fireGridId
		gridInfo.Status++
	}
	return
}

//把玩家当前层变成焦土，tu：玩家，gridIds：焦土坐标，burn 是否将格子烧毁，us攻击玩家
func changeGridFireStatus(tu *m.User, gridIds []int64, midId int64, burn bool, us *m.User) (cntfree int64, err error) {
	layer := CurrentLayer(tu)
	layerT, ok := getLayerTByTid(uint64(layer.Tid))
	if !ok {
		err = errors.NewErrcode(data.Errcode.ConfigNotFound, "没有找到层配置")
		return
	}

	// 焦土格子id
	fireGridId := getFireGridTid(layerT)
	// 记录变成焦土的格子id
	scorchedEarth := make([]int64, 0)

	cntfree = 0 //统计变成焦土的格子数
	for _, id := range gridIds {
		gridInfo := layer.GetGrid(id)
		// 出口门 或者 本身就是焦土
		if id == layer.InGridId || gridInfo.Status == 2 {
			continue
		}
		if gridInfo.Status == 1 {
			gridInfo.ExtId = gridInfo.Tid
		}
		cntfree++
		gridInfo.Tid = fireGridId
		if burn {
			gridInfo.StatusEx = 0 // 格子变成焦土，解锁格子
			gridInfo.Status++
			scorchedEarth = append(scorchedEarth, id)
		}
	}
	// 天灾 us放火玩家是空的
	if burn && us != nil {
		var minId int64 = math.MaxInt64
		midFlag := false
		for _, item := range scorchedEarth {
			if midId == item {
				midFlag = true
			}
			if item < minId {
				minId = item
			}
		}

		if midFlag {
			// 指定格子可以放火，标记攻击玩家的头像和头像框
			gridInfo := layer.GetGrid(midId)
			gridInfo.Head = us.Head
			gridInfo.AvatarFrame = us.AvatarFrame
		} else {
			// 指定格子不能放火，取最小格子id标记头像框
			if minId < math.MaxInt64 {
				gridInfo := layer.GetGrid(minId)
				gridInfo.Head = us.Head
				gridInfo.AvatarFrame = us.AvatarFrame
			}
		}
	}

	// 重置当前关卡打开的格子数
	caculLockBlockOpenGridNum(tu.GetCurrentLockBlock())
	//重置当前层打开的格子数
	tu.ResetCurrentLayerOpenGridNum()
	return
}

//通过Ids获取当前层的格子信息
func GetGridInfoByIds(tu *m.User, gridIds []int64) (gridList map[int64]*m.GridInfo, err error) {
	layer := CurrentLayer(tu)
	gridList = make(map[int64]*m.GridInfo, 0)
	for _, id := range gridIds {
		gridList[id] = layer.GetGrid(id)
	}
	return
}

// 检查所有格子是否被摧毁
func CheckAllGridIsFire(tu *m.User) (r bool, err error) {
	num := 0

	layer := CurrentLayer(tu)

	for _, grid := range layer.GridList {
		if grid.Status > 0 {
			num++
		}
	}
	if num == len(layer.GridList) || num == len(layer.GridList)-1 {
		return true, nil
	}
	return
}
